package com.hmall.search.listener;

import cn.hutool.json.JSONUtil;
import com.hmall.api.client.ItemClient;
import com.hmall.api.dto.ItemDTO;
import com.hmall.common.constants.MQConstants;
import com.hmall.common.utils.BeanUtils;
import com.hmall.search.domain.dto.ItemDoc;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.rest.RestStatus;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;

import static com.hmall.common.constants.ESConstants.ITEM_INDEX;

/**
 * @author ChenPi
 * @since 2025/03/24 14:01
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class ItemListener {

    private final ItemClient itemClient;
    private final RestHighLevelClient client;

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = MQConstants.ITEM_INDEX_QUEUE_NAME, durable = "true"),
            exchange = @Exchange(name = MQConstants.ITEM_EXCHANGE_NAME),
            key = MQConstants.ITEM_INDEX_KEY
    ))
    public void listenItemIndex(Long itemId) throws IOException {
        log.info("商品新增或更新，商品id：{}", itemId);
        // 1.获取商品详情
        ItemDTO itemDTO = itemClient.queryItemById(itemId);

        // 2.实现将文档添加到ES逻辑
        indexDocToES(itemDTO);
        log.info("监听到MQ发送商品新增的消息");

    }


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = MQConstants.ITEM_UPDATE_STATUS_QUEUE_NAME, durable = "true"),
            exchange = @Exchange(name = MQConstants.ITEM_EXCHANGE_NAME),
            key = MQConstants.ITEM_UPDATE_STATUS_KEY
    ))
    public void listenItemStatusChange(Long itemId) throws IOException {
        log.info("商品状态发生变化，商品id：{}", itemId);
        /*
        商品状态 1-正常，2-下架，3-删除
        * */
        // 1.获取商品详情
        ItemDTO itemDTO = itemClient.queryItemById(itemId);
        Integer status = itemDTO.getStatus();
        if (status == 1) {
            // 添加文档到ES索引
            indexDocToES(itemDTO);
        } else {
            // 其他状态处理
            // 删除文档
            listenItemDelete(itemId);
        }

        log.info("监听到MQ发送商品状态变化的消息");
    }

    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = MQConstants.ITEM_DELETE_QUEUE_NAME, durable = "true"),
            exchange = @Exchange(name = MQConstants.ITEM_EXCHANGE_NAME),
            key = MQConstants.ITEM_DELETE_KEY
    ))
    public void listenItemDelete(Long itemId) throws IOException {
        log.info("商品删除，商品id：{}", itemId);
        // 实现从ES中删除逻辑
        deleteDoc(itemId);
        log.info("监听到MQ发送商品删除的消息");
    }

    /**
     * 删除文档
     *
     * @param itemId
     * @throws IOException
     */
    private void deleteDoc(Long itemId) throws IOException {
        // 1.创建request对象
        DeleteRequest request = new DeleteRequest(ITEM_INDEX, itemId.toString());
        // 3.发起请求
        DeleteResponse deleted = client.delete(request, RequestOptions.DEFAULT);
        RestStatus status = deleted.status();
        System.out.println("status = " + status);
    }

    /**
     * 添加文档到ES索引
     *
     * @param itemDTO
     * @throws IOException
     */
    private void indexDocToES(ItemDTO itemDTO) throws IOException {
        // 判断itemDTO是否为空
        if (itemDTO == null) {
        }
        // 将ItemDTO转换为ItemDoc对象
        ItemDoc itemDoc = BeanUtils.copyBean(itemDTO, ItemDoc.class);
        // 2.1.将ItemDTO转json
        String doc = JSONUtil.toJsonStr(itemDoc);

        // 2.2.创建request对象
        IndexRequest request = new IndexRequest(ITEM_INDEX).id(itemDoc.getId());
        // 2.3.准备数据
        request.source(doc, XContentType.JSON);
        // 2.4.发送请求
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);

        System.out.println("response = " + response);
    }
}